/*
 * Copyright (c) 2011 Auzingers
 * Created by Oui-IT
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package com.auzingers.docsorganizer.service;

import com.auzingers.docsorganizer.db.DocsOrganizerDbHelper;
import com.auzingers.docsorganizer.entity.GoogleCollection;

import android.app.Service;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Binder;
import android.os.IBinder;

import java.util.ArrayList;
import java.util.List;

/** Database routines for the db organizer. */
public class DocsOrganizerDbService extends Service {

    private DocsOrganizerDbHelper dbHelper;

    private SQLiteDatabase db;

    /**
     * Class for clients to access.  Because we know this service always
     * runs in the same process as its clients, we don't need to deal with
     * IPC.
     */
    public class LocalBinder extends Binder {
        public DocsOrganizerDbService getService() {
            return DocsOrganizerDbService.this;
        }
    }

    @Override
    public void onCreate() {
        dbHelper = new DocsOrganizerDbHelper(this);
        db = dbHelper.getWritableDatabase();
    }

    @Override
    public void onDestroy() {
        dbHelper.close();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    // This is the object that receives interactions from clients.  See
    // RemoteService for a more complete example.
    private final IBinder mBinder = new LocalBinder();

    /**
     * Inserts the given collection into the database.
     * @param col collection to save
     */
    public void saveCollection(GoogleCollection col) {
        final ContentValues values = new ContentValues();
        values.put("resource_id", col.getResourceId());
        values.put("title", col.getTitle());
        insertOrUpdate("collection", "resource_id", col.getResourceId(), values);
    }

    /**
     * Generic method that performs an insert if it is a new record and an update if it is an existing one.
     * @param table table to write into
     * @param idColumn id column
     * @param idValue value of the id column
     * @param values values to save
     */
    protected void insertOrUpdate(String table, String idColumn, String idValue, ContentValues values) {
        db.beginTransaction();
        //check if the record exists already
        int count = 0;
        Cursor cur = null;
        try {
            cur = db.rawQuery("SELECT COUNT(*) FROM collection WHERE resource_id = ?", new String[] {idValue});
            cur.moveToNext();
            count = cur.getInt(0);
            cur.close();
        } finally {
            if (cur != null) {
                cur.close();
            }
        }

        //perform actual insert or update
        if (count == 0) {
            db.insert(table, null, values);
        } else {
            db.update(table, values, idColumn + " = ?", new String[] {idValue});
        }
        db.setTransactionSuccessful();
        db.endTransaction();
    }

    /**
     * Returns the name of the collection with the given id.
     * @param resourceId id of the collection searching for (just the ID, i.e.
     *     0B0oZ3CeNrlNMNmMxMDJjMjItNDBiMy00NzhiLTkzNTMtMDg4MDcwZmQ4YmZj
     * @return name of the collection
     */
    public String getCollectionName(String resourceId) {
        final String result;
        Cursor cur = null;
        try {
            final String dbResourceId = "folder:" + resourceId;
            cur = db.query("collection", new String[] {"title"}, "resource_id = ?", new String[] {dbResourceId}, null,
                    null, null);
            if (cur.moveToNext()) {
                result = cur.getString(0);
            } else {
                result = null;
            }
        } finally {
            if (cur != null) {
                cur.close();
            }
        }
        return result;
    }

    /**
     * Clears the collection table and stores those collections given.
     * @param collections collections to store
     */
    public void updateCollectionList(List<GoogleCollection> collections) {
        db.beginTransaction();
        db.execSQL("DELETE FROM collection;");
        for (final GoogleCollection col : collections) {
            final ContentValues values = new ContentValues();
            values.put("resource_id", col.getResourceId());
            values.put("title", col.getTitle());
            db.insert("collection", null, values);
        }
        db.setTransactionSuccessful();
        db.endTransaction();
    }

    /**
     * Deletes the collection with the given resource id.
     * @param resourceId resource id of the collection to delete
     */
    public void deleteCollection(String resourceId) {
        db.beginTransaction();
        db.delete("collection", "resource_id = ?", new String[] {resourceId});
        db.setTransactionSuccessful();
        db.endTransaction();
    }

    /**
     * Deletes all entries in the collections table.
     */
    public void clearCollections() {
        db.beginTransaction();
        db.execSQL("DELETE FROM collection;");
        db.setTransactionSuccessful();
        db.endTransaction();
    }

    /**
     * Returns all collections that are stored in the database.
     * @return List of all collections.
     */
    public List<GoogleCollection> getAllCollections() {
        final List<GoogleCollection> result = new ArrayList<GoogleCollection>();
        Cursor cur = null;
        try {
            cur = db.query("collection", new String[] {"resource_id", "title"}, null, new String[0], null, null,
                    "title");
            while (cur.moveToNext()) {
                final GoogleCollection col = new GoogleCollection();
                col.setResourceId(cur.getString(0));
                col.setTitle(cur.getString(1));
                result.add(col);
            }
        } finally {
            if (cur != null) {
                cur.close();
            }
        }
        return result;
    }
}
